package com.spzx.payment.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeCreateRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeCreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.spzx.payment.configure.AlipayConfig;
import com.spzx.payment.domain.PaymentInfo;
import com.spzx.payment.service.IAlipayService;
import com.spzx.payment.service.IPaymentInfoService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author GQS @Date 2024/10/19/16:55 @Description
 */
@Service
@Slf4j
public class AlipayServiceImpl implements IAlipayService {

  @Autowired private AlipayClient alipayClient;

  @Autowired private IPaymentInfoService paymentInfoService;

  @SneakyThrows
  @Override
  public String submitAlipay(String orderNo) {
    // 保存支付记录
    PaymentInfo paymentInfo = paymentInfoService.savePaymentInfo(orderNo);
    // 生产二维码
    AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest(); // 创建API对应的request
    // 同步回调
    alipayRequest.setReturnUrl(AlipayConfig.return_payment_url);
    // alipayRequest.setReturnUrl(AlipayConfig.return_order_url);
    // System.out.println("---------------------------------------------------------------------");
    // 异步回调
    alipayRequest.setNotifyUrl(AlipayConfig.notify_payment_url); // 在公共参数中设置回跳和通知地址
    // 参数
    // 声明一个map 集合
    HashMap<String, Object> map = new HashMap<>();
    map.put("out_trade_no", paymentInfo.getOrderNo());
    map.put("product_code", "QUICK_WAP_WAY");
    // map.put("total_amount",orderInfo.getTotalAmount());
    map.put("total_amount", "0.01");
    map.put("subject", paymentInfo.getContent());

    alipayRequest.setBizContent(JSON.toJSONString(map));

    return alipayClient.pageExecute(alipayRequest).getBody(); // 调用SDK生成表单;
  }

  @Override
  public void closePayment(String orderNo) {
    // 1.查询交易记录
    PaymentInfo paymentInfo =
        paymentInfoService.getOne(
            new LambdaQueryWrapper<>(PaymentInfo.class).eq(PaymentInfo::getOrderNo, orderNo));
    // 2.判断交易记录是否存在 且未支付
    if (paymentInfo != null && paymentInfo.getPaymentStatus() == 0) {
      // 3.产生本地交易记录 要进行关闭
      paymentInfo.setPaymentStatus(-1);
      paymentInfoService.updateById(paymentInfo);
      // 4.查询支付宝交易记录是否关闭
      Boolean flag = this.checkAlipayPayment(orderNo);
      if (flag) {
        this.closeAlipayTrade(orderNo);
      }
    }
  }

  @Override
  public String alipayNotify(Map<String, String> paramMap) {
    log.info("AlipayService...alipayNotify方法执行了...");
    boolean signVerified = false; //调用SDK验证签名
    try {
      signVerified = AlipaySignature.rsaCheckV1(paramMap, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type);
    } catch (AlipayApiException e) {
      e.printStackTrace();
    }

    // 交易状态
    String trade_status = paramMap.get("trade_status");

    // true
    if (signVerified) {
      // TODO 验签成功后，按照支付结果异步通知中的描述，对支付结果中的业务内容进行二次校验，校验成功后在response中返回success并继续商户自身业务处理，校验失败返回failure
      if ("TRADE_SUCCESS".equals(trade_status) || "TRADE_FINISHED".equals(trade_status)) {
        // 正常的支付成功，我们应该更新交易记录状态
        paymentInfoService.updatePaymentStatus(paramMap, 2);
        return "success";
      }
    } else {
      // TODO 验签失败则记录异常日志，并在response中返回failure.
      return "failure";
    }
    return "failure";
  }



  /**
   * 关闭支付宝交易
   * 官方文档：https://opendocs.alipay.com/open/a62e8677_alipay.trade.close?scene=common&pathHash=0801e763
   *
   * @param orderNo
   */
  private Boolean closeAlipayTrade(String orderNo) {
    try {
      // 创建支付宝交易请求对象
      AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
      // 构建业务内容的JSON对象
      JSONObject bizContent = new JSONObject();
      // 向业务内容中添加订单号
      bizContent.put("out_trade_no", orderNo);
      // 设置请求的业务内容
      request.setBizContent(bizContent.toString());

      // 执行支付宝交易创建请求
      AlipayTradeCreateResponse response = alipayClient.execute(request);
      // 检查响应是否成功
      if (response.isSuccess()) {
        // 如果成功，记录日志并返回true
        log.info("支付宝关闭交易调用成功");
        return true;
      } else {
        // 如果失败，记录日志
        log.info("支付宝关闭调用失败");
      }
    } catch (AlipayApiException e) {
      // 捕获异常并打印堆栈跟踪
      e.printStackTrace();
    }
    // 如果执行到此处，表示交易关闭失败或发生异常，返回false
    return false;
  }

  /**
   * 查看是否有交易记录是否可以关闭
   * 官方文档：https://opendocs.alipay.com/open/4e2d51d1_alipay.trade.query?scene=common&pathHash=8abc6ffe
   *
   * @param orderNo
   * @return false:不可以关闭 true:未关闭，可以关闭
   */
  private Boolean checkAlipayPayment(String orderNo) {
    // 创建支付宝交易查询请求对象
    AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
    // 构建业务内容的JSON对象
    JSONObject bizContent = new JSONObject();
    // 将订单号放入业务内容中，用于查询交易信息
    bizContent.put("out_trade_no", orderNo);

    // 设置请求的业务内容
    request.setBizContent(bizContent.toString());

    // 初始化支付宝交易查询响应对象
    AlipayTradeQueryResponse response = null;
    try {
      response = alipayClient.execute(request);
    } catch (AlipayApiException e) {
      e.printStackTrace();
    }
    // 检查响应是否成功
    if (response.isSuccess()) {
      // 交易状态：WAIT_BUYER_PAY（交易创建，等待买家付款）、
      // TRADE_CLOSED（未付款交易超时关闭，或支付完成后全额退款）、
      // TRADE_SUCCESS（交易支付成功）、TRADE_FINISHED（交易结束，不可退款）
      // 当交易状态为等待买家付款时，返回true
      if (response.getTradeStatus().equals("WAIT_BUYER_PAY")) {
        return true;
      }
    }
    // 如果交易状态不是等待买家付款，返回false
    return false;
  }
}
